package edu.ustb.efws.base.mapper.type;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 字符集合转换
 *
 * @author TS Group
 */
@MappedJdbcTypes(JdbcType.VARCHAR)
public class StringListTypeHandler extends BaseTypeHandler<List<String>> {
    private static final Logger LOGGER = LoggerFactory.getLogger(StringListTypeHandler.class);

    /**
     * 数组之间分割符
     */
    private static final char SEPARATOR = ',';

    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, List<String> values, JdbcType jdbcType) throws SQLException {
        String v = (values == null || values.isEmpty()) ? "" : StringUtils.join(values, SEPARATOR);
        preparedStatement.setString(i, v);
    }

    @Override
    public List<String> getNullableResult(ResultSet resultSet, String s) throws SQLException {
        return parseIntList(resultSet.getString(s));
    }

    private List<String> parseIntList(String value) throws SQLException {

        List<String> list = new ArrayList<>();
        if (StringUtils.isBlank(value)) {
            return list;
        }

        try {
            list.addAll(Arrays.asList(StringUtils.split(value, SEPARATOR)));
            return list;
        } catch (Exception e) {
            LOGGER.error("Parse string to int list fail value={}, throw={}", value, e.getMessage());
            throw new SQLException("Parse string to int list fail value=" + value + ", throw=" + e.getMessage());
        }
    }

    @Override
    public List<String> getNullableResult(ResultSet resultSet, int i) throws SQLException {
        return parseIntList(resultSet.getString(i));
    }

    @Override
    public List<String> getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        return parseIntList(callableStatement.getString(i));
    }
}